#include <iostream>
#include <thread>
#include <vector>
#include <sys/eventfd.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <cstring>
#include <cstdint>
#include <functional>
#include <chrono>

// 线程数量
const int THREAD_COUNT = 3;

int main() {
    // 1. 创建 eventfd (初始值为0)
    int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    if (efd == -1) {
        perror("eventfd");
        return 1;
    }

    // 2. 创建 epoll 实例
    int epfd = epoll_create1(0);
    if (epfd == -1) {
        perror("epoll_create1");
        close(efd);
        return 1;
    }

    // 3. 将 eventfd 添加进 epoll
    struct epoll_event ev;
    ev.events = EPOLLIN;   // 只关心可读事件
    ev.data.fd = efd;

    if (epoll_ctl(epfd, EPOLL_CTL_ADD, efd, &ev) == -1) {
        perror("epoll_ctl: add");
        close(epfd);
        close(efd);
        return 1;
    }

    // 4. 创建线程池，每个线程调用 epoll_wait 等待事件
    std::vector<std::thread> threads;

    for (int i = 0; i < THREAD_COUNT; ++i) {
        threads.emplace_back([=]() {
            std::cout << "Thread [" << std::this_thread::get_id() << "] is waiting for event..." << std::endl;

            struct epoll_event events[10];
            while (true) {
                int n = epoll_wait(epfd, events, 10, -1); // 永远等待
                if (n == -1) {
                    perror("epoll_wait error");
                    break;
                }

                for (int j = 0; j < n; ++j) {
                    if (events[j].data.fd == efd && (events[j].events & EPOLLIN)) {
                        uint64_t u;
                        ssize_t s = read(efd, &u, sizeof(uint64_t));
                        if (s != sizeof(uint64_t)) {
                            perror("read eventfd");
                            continue;
                        }

                        std::cout << "Thread [" << std::this_thread::get_id()
                                  << "] received event, count: " << u << std::endl;
                    }
                }
            }
        });
    }

    // 5. 主线程休眠一段时间后发送事件
    std::this_thread::sleep_for(std::chrono::seconds(3));

    std::cout << "Main thread is sending event to all workers..." << std::endl;
    uint64_t u = 1;
    if (write(efd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) {
        perror("write eventfd");
    }

    // 6. 等待所有线程结束（这里为了简单，实际应优雅退出）
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 给子线程足够时间响应
    for (auto& t : threads) {
        if (t.joinable()) {
            t.detach(); // 或者 join()
        }
    }

    // 7. 清理资源
    close(epfd);
    close(efd);

    return 0;
}